package com.fwj.demo01.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/redis")
public class RedisTestController {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @RequestMapping("/test01")
    public String test01() {
        return (String) redisTemplate.opsForValue().get("hello");
    }

    @RequestMapping("/test02")
    public void test02() {
        String uuid = UUID.randomUUID().toString();
        Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid, 3, TimeUnit.MINUTES);
        if (lock) {
            Object value = redisTemplate.opsForValue().get("num");
            if (StringUtils.isEmpty(value)) {
                return;
            }
            int num = Integer.parseInt(value + "");
            redisTemplate.opsForValue().set("num", ++num);
            String lockUid = (String) redisTemplate.opsForValue().get("lock");
            // 如果uuid一样就删除锁
            if (lockUid.equals(uuid)) {
                redisTemplate.delete("lock");
            }
        } else {
            // 隔一秒再获取
            try {
                Thread.sleep(100);
                test02();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @RequestMapping("/luaTest")
    public void luaTest() {
        String uuid = UUID.randomUUID().toString();
        // 设置lock
        Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid, 3, TimeUnit.MINUTES);

        // 如果lock设置成功
        if (lock) {
            Object num = redisTemplate.opsForValue().get("num");
            if (num!=null) {
                int value = Integer.parseInt(num + "");
                redisTemplate.opsForValue().set("num", ++value);
                // 定义lua脚本
                String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
                DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
                redisScript.setScriptText(script);
                redisScript.setResultType(Long.class);
                // 还行lua脚本，完成原子操作
                redisTemplate.execute(redisScript, Arrays.asList("lock"), uuid);
            }
        } else {
            try {
                Thread.sleep(3);
                luaTest();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
